home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c / 495 < prev    next >
Text File  |  1996-08-06  |  5KB  |  144 lines

  1. Newsgroups: comp.lang.c,comp.std.c
  2. Path: uu4news.netcom.com!friend!news
  3. From: rich@kastle.com (Richard Krehbiel)
  4. Subject: Exercise: Help me write a portable sleep() function
  5. Message-ID: <1996Mar4.164124.22845@friend.kastle.com>
  6. Sender: news@friend.kastle.com (News)
  7. Reply-To: rich@kastle.com
  8. Organization: Kastle Development Associates
  9. X-Newsreader: Forte Free Agent 1.0.82
  10. Date: Mon, 4 Mar 1996 16:42:33 GMT
  11.  
  12. As an exercise, I'm trying to write a fully Standard-conforming
  13. portable sleep() function.  I want to make sure it has no undefined
  14. behavior, and it should detect and deal with implementation-specific
  15. behavior.
  16.  
  17. It need not work, only "most probably" work.  :-)
  18.  
  19. Please post corrections and comments, do not just email me.  I'd like
  20. this exercise to be open to the whole public.
  21.  
  22. Here is that I have so far.  I tried this under Windows NT, compiled
  23. with MSVC 4.0, and I got the behavior I expected.
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28. #include <limits.h>
  29.  
  30. /*
  31.   YIELD macro
  32.  
  33.   Perhaps your execution environment may have some means to show
  34.   intent to offer computing time to other processes.  If so, and if
  35.   your compiler allows you to create preprocessor definitions without
  36.   embedding them in this source (rumors are that these are called
  37.   "command line definitions", and I suppose the Standard does not
  38.   forbid this) then a YIELD definition might somehow be provided that
  39.   invokes this procedure.
  40.  
  41. */
  42.  
  43. #ifndef YIELD
  44. #define YIELD                   /* Of course, fully Standard code has
  45.                                    no such function. */
  46. #endif
  47.  
  48. /*
  49.   Following is mysleep_time.  This function uses the time() function
  50.   call to delay for the given amount of time.  If the time() services
  51.   are not provided by this environment, it returns 0; otherwise, it
  52.   returns 1 after at least the given amount of time has elapsed.
  53.  
  54.   It is unfortunate that no means is available to determine if the
  55.   desired amount of delay time cannot be represented by the provided
  56.   timing services.
  57.  
  58. */
  59.  
  60. int mysleep_time(int duration)
  61. {
  62.     time_t start;               /* The time at which timing began */
  63.  
  64.     if((start = time(NULL)) == -1)
  65.         return 0;               /* Sorry, the environment does not
  66.                                    provide this timing-related
  67.                                    service. */
  68.  
  69.     while(difftime(time(NULL), start) <= (double)duration)
  70.         YIELD;
  71.  
  72.     return 1;                   /* Time delay has elapsed. */
  73. }
  74.  
  75. /*
  76.   The following is mysleep_clock.  This function makes use of the
  77.   clock() service, perhaps to provide a more accurate timing interval,
  78.   and perhaps to overcome an environment shortcoming that time() is
  79.   not provided.
  80. */
  81.  
  82. int mysleep_clock(int duration)
  83. {
  84.     clock_t start;
  85.  
  86.     /* I cannot make any assumption regarding the value of
  87.        CLOCKS_PER_SEC if the target environment cannot support
  88.        clock().  Perhaps it may be zero or negative.  I must code to
  89.        prevent the compiler from executing a constant division by
  90.        CLOCKS_PER_SEC to avoid the possibility that my program fail to
  91.        compile in this fully-Standard environment.  */
  92.  
  93.     if(CLOCKS_PER_SEC <= 0)
  94.         return 0;               /* This environment obviously cannot
  95.                                    support clock(). */
  96.  
  97.     {
  98.         int duration_max = INT_MAX;
  99.         duration_max /= CLOCKS_PER_SEC;
  100.         if(duration >= duration_max)
  101.             return 0;
  102.     }
  103.  
  104.     if((start = clock()) == -1)
  105.         return 0;               /* The environment does not provide
  106.                                    such timing services */
  107.  
  108.     duration *= CLOCKS_PER_SEC; /* Scale duration from seconds to
  109.                                    become clock ticks */
  110.  
  111.     while(clock() - start <= duration)
  112.         YIELD;
  113.  
  114.     return 1;
  115. }
  116.  
  117. /*
  118.   Here is the caller's entry point.  The argument is the number of
  119.   seconds of sleep desired.  The return values are 1 if the delay has
  120.   occurred, and 0 if no timing services could be found.  The caller
  121.   should check for this possible failure.
  122.  
  123.   This function will delay for at least the amount of time requested.
  124.   It may delay for an unspecified extra amount of time, depending on
  125.   the resolution of system timing services and the possible scheduling
  126.   of other programs by the execution environment.
  127. */
  128.  
  129. int mysleep(int duration)
  130. {
  131.     /* Try the more accurate version first */
  132.  
  133.     if(mysleep_clock(duration))
  134.         return 1;               /* Timing success. */
  135.  
  136.     return mysleep_time(duration); /* Resort to the time()-based
  137.                                       version */
  138. }
  139.  
  140. --
  141. Richard Krehbiel, Kastle Systems, Arlington VA USA
  142. rich@kastle.com (work) or richk@mnsinc.com (personal)
  143.  
  144.